package com.valenx.distributedmulticamerasystem.camera;


import com.valenx.distributedmulticamerasystem.camera.api.CameraFunction;
import com.valenx.distributedmulticamerasystem.camera.api.OutsideCameraCallBack;
import com.valenx.distributedmulticamerasystem.camera.constant.CameraMode;
import com.valenx.distributedmulticamerasystem.camera.recorder.VideoRecorder;
import com.valenx.distributedmulticamerasystem.camera.utils.LogUtil;
import com.valenx.distributedmulticamerasystem.camera.utils.Nv21Handler;
import com.valenx.distributedmulticamerasystem.camera.view.CameraView;
import com.valenx.distributedmulticamerasystem.utils.OperateStorageFileUtils;
import ohos.agp.graphics.Surface;
import ohos.agp.graphics.SurfaceOps;
import ohos.agp.render.Paint;
import ohos.agp.utils.Color;
import ohos.agp.utils.Rect;
import ohos.app.Context;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.media.camera.CameraKit;
import ohos.media.camera.device.*;
import ohos.media.camera.params.Face;
import ohos.media.camera.params.FaceDetectionResult;
import ohos.media.camera.params.Metadata;
import ohos.media.image.Image;
import ohos.media.image.ImageReceiver;
import ohos.media.image.ImageSource;
import ohos.media.image.PixelMap;
import ohos.media.image.common.ImageFormat;
import ohos.media.image.common.PixelFormat;
import ohos.media.image.common.Size;

import java.io.FileDescriptor;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;

//相机控制器
public class CameraController implements CameraFunction {

    private Context context;//上下文
    private boolean isFrontCamera;//标记：是否为前置摄像头
    private EventHandler eventHandler;//事件处理器

    private Surface previewSurface;//预览画布
    private int previewWidth;//预览宽
    private int previewHeight;//预览高

    private String cameraId;//当前逻辑相机
    private CameraAbility cameraAbility;//相机能力

    private Camera cameraDevice;//相机设备
    private List<Size> supportedSizesJPEG;//JPEG支持分辨率
    private List<Size> supportedSizesH264;//H264支持分辨率

    private VideoRecorder videoRecorder;//录像操作对象
    private Surface recordSurface;//录像画布
    private boolean isRecording;//标记：判断是否正在录像
    private final Object lock = new Object();//线程锁

    private CameraMode cameraMode = CameraMode.PHOTO_MODE;//标记：判断当前相机模式（默认为拍照模式）
    private int flashMode = Metadata.FlashMode.FLASH_CLOSE;//标记：闪光灯模式（默认为关）
    private boolean isMaster;//标记：是否为主机
    private boolean isPushFlowOn;//标记：是否开启推流
    private ImageReceiver imageReceiver;//图片接收器
    private ImageReceiver pushFlowImageReceiver;//推流图片接收器
    private Surface receivingSurface;//图片接收器画布
    private Surface pushFlowReceivingSurface;//推流图片接收器画布
    private OutsideCameraCallBack outsideCameraCallBack;//相机外部回调

    private int resoluteX;//横向分辨率
    private int resoluteY;//纵向分辨率

    public float[] lines;
    public Paint paint;
    public Rect faceRect;
    private CameraView cameraView;
    private int faceDurationFrames = 1;
    int currentFaceNum;
//=============================================================================================================

    //相机控制器构造器
    public CameraController(Context context, boolean isFrontCamera,CameraView cameraView) {
        this.context = context;//相机控制器的上下文
        this.isFrontCamera = isFrontCamera;//当前相机朝向
        this.cameraView = cameraView;
        this.eventHandler = new EventHandler(EventRunner.create(CameraController.class.getSimpleName()));//事件处理器实例
    }

//=============================================================================================================

    //绑定CameraView，获取预览画布及宽高
    @Override
    public void bind(CameraView cameraView) {
        if (cameraView.getSurfaceOps().isPresent()) {
            this.previewSurface = cameraView.getSurfaceOps().get().getSurface();
            this.previewWidth = cameraView.getWidth();
            this.previewHeight = cameraView.getHeight();
            openCamera();//打开相机
        }
    }
//=============================================================================================================

    //打开相机
    @Override
    public void openCamera() {
        CameraKit cameraKit = CameraKit.getInstance(context.getApplicationContext());//创建相机套件
        if (cameraKit == null) {
            return;// 处理cameraKit获取失败的情况
        }

        //此处isFrontCamera表示当前应该是什么相机（前后置切换相关）
        String[] cameraList = cameraKit.getCameraIds();//获取逻辑相机列表
        //获得与朝向匹配的逻辑相机ID
        for (String logicalCameraId : cameraList) {//从逻辑相机列表中逐一取出逻辑相机ID
            int faceType = cameraKit.getCameraInfo(logicalCameraId).getFacingType();//当前逻辑相机的朝向
            switch (faceType) {
                case CameraInfo.FacingType.CAMERA_FACING_FRONT://当前朝向为前置
                    if (isFrontCamera) {//如果当前标记也是前置
                        cameraId = logicalCameraId;
                    }
                    break;
                case CameraInfo.FacingType.CAMERA_FACING_BACK://当前朝向为后置
                    if (!isFrontCamera) {//如果当前标记也是后置
                        cameraId = logicalCameraId;
                    }
                    break;
                case CameraInfo.FacingType.CAMERA_FACING_OTHERS://当前朝向为其他
                default:
                    break;
            }
        }

        cameraAbility = cameraKit.getCameraAbility(cameraId);
        MyCameraStatusCallback cameraStateCallback = new MyCameraStatusCallback();//创建相机回调
        cameraKit.createCamera(cameraId, cameraStateCallback, eventHandler);//创建相机

        LogUtil.info("CameraController:", "openCamera()-完成 相机创建完成，进入相机状态回调");
    }
//=============================================================================================================




//=============================================================================================================

    //相机状态回调实现类
    private class MyCameraStatusCallback extends CameraStateCallback {
        @Override
        //相机创建完成后（进行初始相机配置）
        //（+预览画布 +图片接收器画布）
        public void onCreated(Camera camera) {
            super.onCreated(camera);
            cameraDevice = camera;//获得相机设备对象
//-----------------------------------------------------初始相机配置-----------------------------------------------
            receiverInit();//图片接收器初始化
            //【初始相机配置（用于拍照+预览）】（+预览画布 +图片接收器）
            if (previewSurface == null) {
                return;
            }
            CameraConfig.Builder cameraConfigBuilder = camera.getCameraConfigBuilder();//获取相机配置器

            cameraConfigBuilder.addSurface(previewSurface);//将【预览画布】配置给相机
            cameraConfigBuilder.addSurface(receivingSurface);//将【图片接收器画布】配置给相机

            cameraConfigBuilder.setFrameStateCallback(new MyFrameStateCallback(), eventHandler);// 配置帧结果的回调
            CameraConfig cameraConfig = cameraConfigBuilder.build();//生成相机配置
            camera.configure(cameraConfig);//配置生效


            LogUtil.info("CameraController:", "cameraStateCallback-onCreated()-初始相机配置完成");
        }
//------------------------------------------------------初始帧配置------------------------------------------------

        //相机配置完成后（进行帧配置）
        @Override
        public void onConfigured(Camera camera) {
            super.onConfigured(camera);

            //相机配置完后回调，初始化编解码器
            if (outsideCameraCallBack != null) {
                outsideCameraCallBack.onCameraConfigured(CameraController.this);
            }

            //如果当前是【拍照模式】（按预览进行帧配置）
            if (cameraMode == CameraMode.PHOTO_MODE) {
                previewFrameConfig();//预览帧配置
            }
            //如果当前是【录像模式】（按录像进行帧配置）（+预览画布 +录像画布）
            else if (cameraMode == CameraMode.RECORD_MODE) {
                videoFrameConfig();//录像帧配置
            }
        }
    }
//=============================================================================================================




//*************************************************************************************************************

    //帧结果回调实现类
    private class MyFrameStateCallback extends FrameStateCallback {
        @Override
        public void onFrameStarted(Camera camera, FrameConfig frameConfig, long frameNumber, long timestamp) {
            super.onFrameStarted(camera, frameConfig, frameNumber, timestamp);
        }

        @Override
        public void onFrameProgressed(Camera camera, FrameConfig frameConfig, FrameResult frameResult) {
            super.onFrameProgressed(camera, frameConfig, frameResult);
        }

        @Override
        public void onFrameFinished(Camera camera, FrameConfig frameConfig, FrameResult frameResult) {
            super.onFrameFinished(camera, frameConfig, frameResult);

            //人脸识别框
            FaceDetectionResult faceDetectionResult = frameResult.getFaceDetectionResult();
            Face[] faces = faceDetectionResult.getFaces();
            if (faces == null || faces.length == 0) {
                if (faceRect != null){
                    paint.setAlpha(0.0f);
                    context.getUITaskDispatcher().asyncDispatch(new Runnable() {
                        @Override
                        public void run() {
                            cameraView.invalidate();
                        }
                    });
                }
                currentFaceNum = 0;
                faceDurationFrames = 1;
                return;
            }

            if (faceDurationFrames ==1) currentFaceNum = faces.length;
            if (currentFaceNum == faces.length){
                faceDurationFrames++;
            }else faceDurationFrames = 1;

            if (faceDurationFrames <= 30){
                faceRect = faces[0].getFaceRect();
                faceRect.rotateBy(Rect.RotationEnum.ROTATE_90);

                float ax = faceRect.left *2/3;
                float ay = faceRect.top;

                float bx = faceRect.right *2/3;
                float by = faceRect.top;

                float cx = faceRect.right *2/3;
                float cy = faceRect.bottom;

                float dx = faceRect.left *2/3;
                float dy = faceRect.bottom;

                lines = new float[]{ax, ay, bx, by,//ab边
                        bx, by, cx, cy,//bc边
                        cx, cy, dx, dy,//cd边
                        dx, dy, ax, ay};//da边
                paint = new Paint();
                paint.setAntiAlias(true);
                paint.setDither(true);
                paint.setStrokeWidth(5);
                paint.setColor(Color.WHITE);

                if (faceDurationFrames >=20){
                    int remainFrame = 30 - faceDurationFrames;
                    float Alpha = 0.1f * remainFrame;
                    paint.setAlpha(Alpha);
                }else paint.setAlpha(1.0f);

                context.getUITaskDispatcher().asyncDispatch(new Runnable() {
                    @Override
                    public void run() {
                        cameraView.invalidate();
                    }
                });
            }
            else {
                paint.setAlpha(0.0f);
                context.getUITaskDispatcher().asyncDispatch(new Runnable() {
                    @Override
                    public void run() {
                        cameraView.invalidate();
                    }
                });
            }


        }

        @Override
        public void onFrameError(Camera camera, FrameConfig frameConfig, int errorCode, FrameResult frameResult) {
            super.onFrameError(camera, frameConfig, errorCode, frameResult);
        }

        @Override
        public void onCaptureTriggerStarted(Camera camera, int captureTriggerId, long firstFrameNumber) {
            super.onCaptureTriggerStarted(camera, captureTriggerId, firstFrameNumber);
        }

        @Override
        public void onCaptureTriggerFinished(Camera camera, int captureTriggerId, long lastFrameNumber) {
            super.onCaptureTriggerFinished(camera, captureTriggerId, lastFrameNumber);
        }

        @Override
        public void onCaptureTriggerInterrupted(Camera camera, int captureTriggerId) {
            super.onCaptureTriggerInterrupted(camera, captureTriggerId);
        }
    }
//*************************************************************************************************************




//*************************************************************************************************************

    //接收器初始化
    @Override
    public void receiverInit() {
        supportedSizesJPEG = cameraAbility.getSupportedSizes(ImageFormat.JPEG);//当前相机支持的JPEG分辨率列表

        imageReceiver = ImageReceiver.create(
                Math.max(supportedSizesJPEG.get(0).height, supportedSizesJPEG.get(0).width),
                Math.min(supportedSizesJPEG.get(0).height, supportedSizesJPEG.get(0).width),
                ImageFormat.JPEG, 9);//创建拍照图片接收器
        receivingSurface = imageReceiver.getRecevingSurface();//获取拍照图片接收器画布
        imageReceiver.setImageArrivalListener(CameraController.this::saveImage);//创建拍照图片接收器监听事件

        //如果是从机，则创建推流图片接收器
        if (!isMaster){
            pushFlowImageReceiver = ImageReceiver.create(
                    1440,
                    720,
                    ImageFormat.YUV420_888, 9);//创建推流图片接收器
            pushFlowReceivingSurface = pushFlowImageReceiver.getRecevingSurface();//获取推流图片接收器画布
            pushFlowImageReceiver.setImageArrivalListener(new PushFlowImageArrivalListener());//创建推流图片接收器监听事件
        }

//        setResolution();

    }
//*************************************************************************************************************




//*************************************************************************************************************

    //图片接收器监听接口实现类
    private class PushFlowImageArrivalListener implements ImageReceiver.IImageArrivalListener {
        //设置一个数据缓存区
        private final List<byte[]> buffers = new ArrayList<>(5);
        private int index;

        //构造器
        PushFlowImageArrivalListener() {
            for (int i = 0; i < 5; i++) {
                buffers.add(new byte[1440 * 720 * 3 / 2]);
            }
        }

        //获取缓冲
        private byte[] getBuffer() {
            index++;
            if (index == 5) {
                index = 0;
            }
            return buffers.get(index);
        }

        @Override
        public void onImageArrival(ImageReceiver receiver) {
            LogUtil.info("CameraController:", "推流onImageArrival回调");
            byte[] bytes;
            Image image = pushFlowImageReceiver.readNextImage();

                bytes = getBuffer();
                Image.Component component = image.getComponent(ImageFormat.ComponentType.YUV_Y);

                if (component == null) return;

                component.read(bytes, 0, component.remaining());

                component = image.getComponent(ImageFormat.ComponentType.YUV_U);
                ByteBuffer mBuffer = component.getBuffer();
                mBuffer.get(
                        bytes,
                        1440 * 720,
                        Math.min(mBuffer.remaining(), 1440 * 720 / 2));

                if (isFrontCamera()) {
                    bytes = Nv21Handler.rotateYuvDegree270AndMirror(bytes, 1440, 720);
                } else {
                    bytes = Nv21Handler.rotateYuv420Degree90(bytes, 1440, 720);//原始的yuv420---nv21格式的数据
                }



            image.release();
            if (outsideCameraCallBack != null) {
                outsideCameraCallBack.onGetPushFlowOriginalData(bytes); //传出原始数据
            }
        }
    }

//-------------------------------------------------------------------------------------------------------------

    //保存图片到外部存储
    private void saveImage(ImageReceiver receiver) {

        ohos.media.image.Image image = receiver.readNextImage();//获取图片
        if (image == null) {
            return;
        }
        ohos.media.image.Image.Component component = image.getComponent(ImageFormat.ComponentType.JPEG);//将图片转为组件
        byte[] photoBytes = new byte[component.remaining()];//创建存放图片数据的数组
        component.read(photoBytes);//将图片数据读入数组

        String photoFileName = "多机位相片_" + System.currentTimeMillis() + ".jpg";//照片文件名
        FileDescriptor photoFD = OperateStorageFileUtils
                .getPublicFdForInsert(context, OperateStorageFileUtils.MediaType.IMAGE, photoFileName);//获取文件描述符

        //输出流向外部存储写入数据
        try(FileOutputStream outputStream = new FileOutputStream(photoFD)){
            outputStream.write(photoBytes);
            outputStream.flush();
        }catch (Exception e){
            LogUtil.error("CameraController:", "保存图片失败");
        }

        outsideCameraCallBack.onImageSaved(getThumbnail(photoBytes));//传出缩略图

        LogUtil.info("CameraController:", "saveImage()-完成");
    }
//*************************************************************************************************************




//*************************************************************************************************************

    //获取缩略图
    @Override
    public PixelMap getThumbnail(byte[] photoBytes){
    ImageSource.SourceOptions sourceOptions = new ImageSource.SourceOptions();//创建图片源配置
    sourceOptions.formatHint = "image/jpg";//设置MIME
    ImageSource imageSource = null;

    //创建图片源
   if (photoBytes != null) {
        imageSource = ImageSource.create(photoBytes, sourceOptions);
    } else {
        return null;
    }

    ImageSource.DecodingOptions decodingOpts = new ImageSource.DecodingOptions();//解码配置
    decodingOpts.desiredSize = new Size(0, 0);
//    decodingOpts.rotateDegrees = (isFrontCamera ? 270 : 90);
    decodingOpts.desiredPixelFormat = PixelFormat.ARGB_8888;
    return imageSource.createPixelmap(decodingOpts);
}
//*************************************************************************************************************




//===================================================配置合集===================================================
//====================================================相机====================================================
    //【拍照专用相机配置（用于拍照+预览）】（+预览画布 +图片接收器）
    @Override
    public void photoCameraConfig() {
        synchronized (lock) {
            CameraConfig.Builder cameraConfigBuilder = cameraDevice.getCameraConfigBuilder();//获取相机配置器
            try {
                cameraConfigBuilder.addSurface(previewSurface);//将预览画布加入相机配置
                if (receivingSurface != null) {//如果图片接收器画布非空
                    cameraConfigBuilder.addSurface(receivingSurface);//将【图片接收器画布】加入相机配置
                }
                if (!isMaster && isPushFlowOn){
                    cameraConfigBuilder.addSurface(pushFlowReceivingSurface);//如果是从机，将【推流图片接收器画布】配置给相机
                }

                cameraConfigBuilder.setFrameStateCallback(new MyFrameStateCallback(), eventHandler);// 配置帧结果的回调
                CameraConfig photoCameraConfig = cameraConfigBuilder.build();//生成相机配置
                cameraDevice.configure(photoCameraConfig);//配置生效（进入相机回调的onConfigured方法进行帧配置）
            } catch (IllegalStateException | IllegalArgumentException e) {
                LogUtil.error("CameraController:", "拍照专用相机配置失败");
            }
        }

        LogUtil.info("CameraController:", "拍照专用相机配置完成：+预览画布+图片接收器画布");
    }

//=============================================================================================================
    //【录像专用相机配置（用于录像）】（+预览画布 +录像画布）
    @Override
    public void videoCameraConfig() {
        synchronized (lock) {
            CameraConfig.Builder cameraConfigBuilder = cameraDevice.getCameraConfigBuilder();//获取相机配置器
            recordSurface = videoRecorder.getRecordSurface().get();//获得录像画布
            try {
                cameraConfigBuilder.addSurface(previewSurface);//将【预览画布】加入相机配置
                if (recordSurface != null) {//如果录像画布非空
                    cameraConfigBuilder.addSurface(recordSurface);//将【录像画布】加入相机配置
                }
                if (!isMaster && isPushFlowOn){
                    cameraConfigBuilder.addSurface(pushFlowReceivingSurface);//如果是从机，将【推流图片接收器画布】配置给相机
                }

                cameraConfigBuilder.setFrameStateCallback(new MyFrameStateCallback(), eventHandler);// 配置帧结果的回调
                CameraConfig videoCameraConfig = cameraConfigBuilder.build();//生成录像专用相机配置
                cameraDevice.configure(videoCameraConfig);//配置生效（进入相机回调的onConfigured方法进行帧配置）
            } catch (IllegalStateException | IllegalArgumentException e) {
                LogUtil.error("CameraController:", "录像专用相机配置失败");
            }
        }

        LogUtil.info("CameraController:", "录像专用相机配置完成：+预览画布+录像画布");

    }

//=====================================================帧=====================================================
    //【预览帧配置】（+预览画布 ○循环帧捕获）
    @Override
    public void previewFrameConfig() {
        FrameConfig.Builder previewFrameConfigBuilder = cameraDevice.getFrameConfigBuilder(Camera.FrameConfigType.FRAME_CONFIG_PREVIEW);//获取帧配置器（类型为预览）
        previewFrameConfigBuilder.addSurface(previewSurface);//将【预览画布】加入帧配置
        if (!isMaster && isPushFlowOn){
            previewFrameConfigBuilder.addSurface(pushFlowReceivingSurface);//如果是从机，将【推流图片接收器画布】加入帧配置
        }
        previewFrameConfigBuilder.setFlashMode(flashMode);//闪光灯配置
        previewFrameConfigBuilder.setFaceDetection(Metadata.FaceDetectionType.FACE_DETECTION, true);//人脸检测
        previewFrameConfigBuilder.setAfMode(Metadata.AfMode.AF_MODE_CONTINUOUS, new Rect(100, 100, 100, 100));//对焦模式


        FrameConfig previewFrameConfig = previewFrameConfigBuilder.build();//生成预览帧配置
        cameraDevice.triggerLoopingCapture(previewFrameConfig);//配置生效，并启动相机循环帧捕获（预览）

        LogUtil.info("CameraController:", "cameraStateCallback-onConfigured()-（预览）帧配置完成（+预览画布 ○循环帧捕获）闪光灯模式：" + flashMode);
    }

//=============================================================================================================
    //【拍照帧配置】（+图片接收器画布）
    @Override
    public FrameConfig photoFrameConfig() {
        FrameConfig.Builder photoFrameConfigBuilder = cameraDevice.getFrameConfigBuilder(Camera.FrameConfigType.FRAME_CONFIG_PICTURE);//获取帧配置器（类型为拍照）
        photoFrameConfigBuilder.addSurface(receivingSurface);//将【图片接收器画布】配置给帧
        if (!isMaster && isPushFlowOn){
            photoFrameConfigBuilder.addSurface(pushFlowReceivingSurface);//如果是从机，将【推流图片接收器画布】加入帧配置
        }
        photoFrameConfigBuilder.setFlashMode(flashMode);//闪光灯配置
        photoFrameConfigBuilder.setFaceDetection(Metadata.FaceDetectionType.FACE_DETECTION, true);//人脸检测
        photoFrameConfigBuilder.setAfMode(Metadata.AfMode.AF_MODE_CONTINUOUS, new Rect(100, 100, 100, 100));//对焦模式

        photoFrameConfigBuilder.setImageRotation(isFrontCamera() ? 270 : 90);
        FrameConfig photoFrameConfig = photoFrameConfigBuilder.build();//生成拍照帧配置

        LogUtil.info("CameraController:", "cameraStateCallback-onConfigured()-（拍照）帧配置完成（+图片接收器画布） 闪光灯模式：" + flashMode);
        return photoFrameConfig;
    }

//=============================================================================================================
    //【录像帧配置】（+预览画布 +录像画布）
    @Override
    public void videoFrameConfig() {
        FrameConfig.Builder videoFrameConfigBuilder = cameraDevice.getFrameConfigBuilder(Camera.FrameConfigType.FRAME_CONFIG_RECORD);//获取帧配置器（类型为录像）
        videoFrameConfigBuilder.addSurface(previewSurface);//将【预览画布】加入帧配置
        if (isRecording && recordSurface != null) {//如果正在录像且录像画布非空
            videoFrameConfigBuilder.addSurface(recordSurface);//将【录像画布】加入帧配置
        }
        if (!isMaster && isPushFlowOn){
            videoFrameConfigBuilder.addSurface(pushFlowReceivingSurface);//如果是从机，将【推流图片接收器画布】加入帧配置
        }
        videoFrameConfigBuilder.setFlashMode(flashMode);//闪光灯配置
        videoFrameConfigBuilder.setFaceDetection(Metadata.FaceDetectionType.FACE_DETECTION, true);//人脸检测
        videoFrameConfigBuilder.setAfMode(Metadata.AfMode.AF_MODE_CONTINUOUS, new Rect(100, 100, 100, 100));//对焦模式

        FrameConfig videoFrameConfig = videoFrameConfigBuilder.build();//生成录像专用帧配置
        LogUtil.info("CameraController:", "cameraStateCallback-onConfigured()-（录像）帧配置完成（+预览画布 +录像画布） 闪光灯模式：" + flashMode);

        cameraDevice.triggerLoopingCapture(videoFrameConfig);//配置生效，并启动相机循环帧捕获（录像）
        LogUtil.info("CameraController:", "○启动录像循环帧捕获");
        if (isRecording) {
            eventHandler.postTask(() -> videoRecorder.start());//开始录像
        }
    }

//=============================================================================================================




//*************************************************************************************************************

    //初始化录像媒体配置
    @Override
    public void initMediaRecorder() {
        String videoFileName = "多机位录像_" + System.currentTimeMillis() + ".mp4";//录像文件名
        FileDescriptor videoFD = OperateStorageFileUtils
                .getPublicFdForInsert(context, OperateStorageFileUtils.MediaType.VIDEO, videoFileName);//获取录像文件标识符

        videoRecorder = new VideoRecorder.Builder()
                .setResolution(new Size(1440, 720))
                .setDegrees(isFrontCamera ? 270 : 90)
                .setSaveFd(videoFD)
                .build();
        videoRecorder.prepare();

        LogUtil.info("CameraController:", "initMediaRecorder()-完成");
    }
//*************************************************************************************************************

    //停止录像（+预览画布 ×停止循环帧捕获（录像））
    @Override
    public void stopRecord() {
        synchronized (lock) {
            try {
                eventHandler.postTask(() -> videoRecorder.stop());
                if (cameraDevice == null || cameraDevice.getCameraConfigBuilder() == null) {//如果相机设备为空或者相机配置器为空，报错
                    LogUtil.error("CameraController:", "停止录像失败,相机设备为空");
                    return;
                }
                CameraConfig.Builder cameraConfigBuilder = cameraDevice.getCameraConfigBuilder();//获取相机配置器
                cameraConfigBuilder.addSurface(previewSurface);//将预览画布加入相机配置
                if (!isMaster && isPushFlowOn){
                    cameraConfigBuilder.addSurface(pushFlowReceivingSurface);//如果是从机，将【推流图片接收器画布】配置给相机
                }
                cameraDevice.configure(cameraConfigBuilder.build());//配置生效（进入相机回调的onConfigured方法进行帧配置）
            } catch (IllegalStateException | IllegalArgumentException exception) {
                LogUtil.error("CameraController:", "停止录像失败");
            }
        }

        LogUtil.info("CameraController:", "相机配置：+预览画布，停止录像");
    }

//*************************************************************************************************************








//*************************************************************************************************************
    //切换相机
    @Override
    public void switchCamera() {
        isFrontCamera = !isFrontCamera;//前置摄像头标记取反
        if (cameraDevice != null) {//如果相机设备非空，则先释放相机
            cameraDevice.release();
        }
        openCamera();//开启新相机

        LogUtil.info("CameraController:", "switchCamera()-完成");
    }
//*************************************************************************************************************

//*************************************************************************************************************
    //释放相机设备
    @Override
    public void releaseCamera() {
        if (cameraDevice != null) {
            // 关闭相机和释放资源
            cameraDevice.release();
            cameraDevice = null;
        }

        //图片接收器释放
        if (imageReceiver != null) {
            imageReceiver.release();
        }

        LogUtil.info("CameraController:", "releaseCamera()-完成");

    }
//*************************************************************************************************************




//************************************************Getter&Setter************************************************
//*************************************************************************************************************

    //设置外部回调（传出数据）
    @Override
    public void setOutsideCameraCallBack(OutsideCameraCallBack outsideCameraCallBack) {
        this.outsideCameraCallBack = outsideCameraCallBack;
    }
//-------------------------------------------------------------------------------------------------------------

    //设置主从标识
    public void setIsMaster(boolean isMaster) {
        this.isMaster = isMaster;
    }
//-------------------------------------------------------------------------------------------------------------

    //获取当前前后置相机状态
    @Override
    public boolean isFrontCamera() {
        return this.isFrontCamera;
    }
//-------------------------------------------------------------------------------------------------------------

    //获取当前相机设备
    public Camera getCameraDevice() {
        return cameraDevice;
    }
//-------------------------------------------------------------------------------------------------------------

    //获取当前录像状态
    public boolean isRecording() {
        return this.isRecording;
    }
//-------------------------------------------------------------------------------------------------------------

    //设置当前录像状态
    public void setIsRecording(Boolean isRecording) {
        this.isRecording = isRecording;
    }
//-------------------------------------------------------------------------------------------------------------

    //获取推流状态
    public boolean getIsPushFlowOn() {
    return this.isPushFlowOn;
}
//-------------------------------------------------------------------------------------------------------------

    //设置推流状态
    public void setIsPushFlowOn(boolean isPushFlowOn) {
        this.isPushFlowOn = isPushFlowOn;
    }
//-------------------------------------------------------------------------------------------------------------

    //获取当前相机拍摄模式
    public CameraMode getCameraMode() {
        return this.cameraMode;
    }
//-------------------------------------------------------------------------------------------------------------

    //设置当前相机拍摄模式
    public void setCameraMode(CameraMode cameraMode) {
        this.cameraMode = cameraMode;
    }
//-------------------------------------------------------------------------------------------------------------

    //获取当前闪光灯模式
    public int getFlashMode() {
        return flashMode;
    }
//-------------------------------------------------------------------------------------------------------------

    //设置当前闪光灯模式
    public void setFlashMode(int flashMode) {
        this.flashMode = flashMode;
    }
//-------------------------------------------------------------------------------------------------------------

    //设置分辨率
    private void setResolution() {
        List<Size> resolutions = getSupportedResolutions();
        if (resolutions != null) {
            //CameraView的宽高比
            double baseResolution = (double) Math.max(previewHeight, previewWidth) / Math.min(previewHeight, previewWidth);
            double minDeference = baseResolution;
            for (Size resolution : resolutions) {
                //支持分辨率的宽高比
                double resolutionTemp = (double) resolution.width / resolution.height;
                double difference = Math.abs(baseResolution - resolutionTemp);
                //获取与CameraView宽高比最接近的支持分辨率
                if (difference < minDeference) {
                    minDeference = difference;
                    resoluteX = resolution.width;
                    resoluteY = resolution.height;
                }
            }
        }
    }
//-------------------------------------------------------------------------------------------------------------

    //获取分辨率
    public Size getResolution() {
        return new Size(resoluteX, resoluteY);
    }

//-------------------------------------------------------------------------------------------------------------

    //获取支持分辨率
    public List<Size> getSupportedResolutions() {
        List<Size> sizes = null;
        if (cameraAbility != null) {
            sizes = cameraAbility.getSupportedSizes(SurfaceOps.class);
        }
        return sizes;
    }
//*************************************************************************************************************

}
